using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using HslCommunicationEx;

namespace AcqEncoder.TcpIp
{
	public class TcpClientSimple
	{
		private Socket _socketClient;

		public bool IsConnected => this._socketClient?.Connected ?? false;

		public OperateRet ConnectServer(string ipAdr, int port)
		{
			OperateRet operateRet = new OperateRet();
			IPAddress iPAddress = IPAddress.Parse(ipAdr);
			IPEndPoint remoteEP = new IPEndPoint(iPAddress, port);
			this._socketClient = new Socket(iPAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
			try
			{
				this._socketClient.Connect(remoteEP);
				operateRet.Success = this._socketClient.Connected;
				return operateRet;
			}
			catch (Exception ex)
			{
				operateRet.Message = ex.ToString();
				return operateRet;
			}
		}

		public GOperateRet<int> SendStr(string str, int outTime)
		{
			return this.SendByte(Encoding.Default.GetBytes(str), outTime);
		}

		public GOperateRet<int> SendByte(byte[] buffer, int outTime)
		{
			GOperateRet<int> gOperateRet = new GOperateRet<int>();
			if (this._socketClient == null || !this._socketClient.Connected)
			{
				gOperateRet.Message = "please connect server first!";
				return gOperateRet;
			}
			if (buffer == null || buffer.Length == 0)
			{
				gOperateRet.Message = "invalid param buffer";
				return gOperateRet;
			}
			int num = buffer.Length;
			int num2 = 0;
			try
			{
				while (this._socketClient.Poll(outTime * 1000000, SelectMode.SelectWrite))
				{
					num2 = this._socketClient.Send(buffer, num2, num, SocketFlags.None);
					num -= num2;
					if (num == 0)
					{
						gOperateRet.Success = true;
						return gOperateRet;
					}
					if (num > 0 || num >= 0)
					{
						continue;
					}
					gOperateRet.Message = "send error";
					return gOperateRet;
				}
				gOperateRet.Message = "send timeout";
				return gOperateRet;
			}
			catch (Exception ex)
			{
				gOperateRet.Message = ex.ToString();
				return gOperateRet;
			}
		}

		public OperateRet ReceiveStr(ref string str)
		{
			byte[] rcvData = null;
			OperateRet operateRet = this.ReceiveByte(ref rcvData);
			if (operateRet.Success && rcvData != null)
			{
				str = Encoding.ASCII.GetString(rcvData);
			}
			return operateRet;
		}

		public OperateRet ReceiveByte(ref byte[] rcvData)
		{
			OperateRet operateRet = new OperateRet();
			if (this._socketClient == null || !this._socketClient.Connected)
			{
				operateRet.Message = "未建立连接";
				return operateRet;
			}
			try
			{
				string text = "";
				List<byte> list = new List<byte>();
				while (this._socketClient.Available > 0)
				{
					byte[] array = new byte[this._socketClient.Available];
					this._socketClient.Receive(array);
					list.AddRange(array);
					Thread.Sleep(10);
				}
				if (list.Count > 0)
				{
					rcvData = list.ToArray();
					byte[] array2 = rcvData;
					foreach (byte b in array2)
					{
						text = text + b.ToString("X2") + " ";
					}
				}
				operateRet.Success = true;
				return operateRet;
			}
			catch (Exception innerException)
			{
				throw new Exception("接收失败", innerException);
			}
		}

		public void DisposeSocket()
		{
			this._socketClient?.Close();
		}

		public static bool Ping(string ip, int timeout = 2000)
		{
			Ping ping = new Ping();
			try
			{
				PingReply pingReply = ping.Send(ip, timeout);
				if (pingReply != null && pingReply.Status == IPStatus.Success)
				{
					return true;
				}
				return false;
			}
			catch (Exception)
			{
				return false;
			}
		}
	}
}
